//시간 단위를 정한다. (단위시간)/(정밀도)
`timescale 10ns/1ps

module multiplier_test;

//변수 선언 부분. 모듈 인스턴스의 입출력을 만듦.
//모듈 인스턴스로의 입력은 우리가 값을 직접 조작할 수 있도록 reg로 넣는다.
//인스턴스에서의 출력은 나오는 거 보기만 하면 되므로 wire
reg iClk;
reg [7:0] iMultiplier, iMultiplicand;
reg iReset, iReady;

wire oDone;
wire [15:0] oProduct;

//.*은 포트 이름과 변수 이름이 일치하는 것끼리 다 이으라는 뜻.
multiplier U1(.*);

//initial begin..end는 블록 안의 내용이 시뮬레이션 처음 한 번만 실행
//여기서는 클록을 만듦.
initial begin
iClk=1'b0;
forever #0.5 iClk=~iClk; //(단위시간)*0.5 동안의 시간마다 클록의 값을 반전.
end

//두 개의 initial 문이 병렬로 동작한다. 여기서는 입력값들을 조작.
//fork...join은 begin...end와 같은 블록임. 대신, 쓰는 시간 단위가 시뮬레이션 시작으로부터의 절대시간.
initial fork
//처음 동작. 리셋을 넣었다 풀어주고, 곱할 값들을 정하고, 조금 있다가 ready를 넣어줌.
//12*9=108
#0 {iReset, iReady}<=2'b1_0; //{}는 두 개 이상의 변수나 숫자를 묶어서 하나의 벡터로 만들어 준다.
#0 {iMultiplier, iMultiplicand} <= 16'b00001100_00001001; //숫자 중의 _는 무시된다. 보기 좋으라고 넣어 주면 좋음.
#2 iReset<=1'b0;
#3 iReady<=1'b1;

//레디를 그대로 두고 곱셈할 수만 바꿈.
//여기에서 #5는 시뮬레이션 시작 후 (단위시간)*5 의 시간이 자난 후, 바로 다음에 있는 명령을 실행하라는 뜻.
//-1*-1=1
#5 {iMultiplier, iMultiplicand} <= 16'b11111111_11111111;

//레디만 풀었다 넣어줄 때
#10 iReady<=1'b0;
#11 iReady<=1'b1;

//리셋 시험.
#20 {iReset, iReady}<=2'b1_0;
#20 {iMultiplier, iMultiplicand} <= 16'b11111111_11111111;
#21 iReset<=1'b0;
#22 iReady<=1'b1;

//레디만 바꿔서 새로운 수로 곱셈하기
//이하 여러 값에 대한 시험
#30 iReady<=1'b0;
#30 {iMultiplier, iMultiplicand} <= 16'b00001100_00001001;
#31 iReady<=1'b1;

#40 iReady<=1'b0;
#40 {iMultiplier, iMultiplicand} <= 16'b00010000_00010000;
#41 iReady<=1'b1;

#50 iReady<=1'b0;
#50 {iMultiplier, iMultiplicand} <= 16'b00100000_00100000;
#51 iReady<=1'b1;

#60 iReady<=1'b0;
#60 {iMultiplier, iMultiplicand} <= 16'b01000000_01000000;
#61 iReady<=1'b1;

#70 iReady<=1'b0;
#70 {iMultiplier, iMultiplicand} <= 16'b10000000_10000000;
#71 iReady<=1'b1;

#80 iReady<=1'b0;
#80 {iMultiplier, iMultiplicand} <= 16'b01111111_01111111;
#81 iReady<=1'b1;

#90 iReady<=1'b0;
#90 {iMultiplier, iMultiplicand} <= 16'b10000000_01111111;
#91 iReady<=1'b1;

#100 iReady<=1'b0;
#100 {iMultiplier, iMultiplicand} <= 16'b01111111_10000000;
#101 iReady<=1'b1;

#110 iReady<=1'b0;
#110 {iMultiplier, iMultiplicand} <= 16'b00001000_10000000;
#111 iReady<=1'b1;

#120 iReady<=1'b0;
#120 {iMultiplier, iMultiplicand} <= 16'b11111100_11111100;
#121 iReady<=1'b1;
join

endmodule